#include "websocket_protocol.h"
#include "board.h"
#include "system_info.h"
#include "application.h"

#include <cstring>
#include <cJSON.h>
#include <esp_log.h>
#include <arpa/inet.h>

#define TAG "WS"

WebsocketProtocol::WebsocketProtocol() {
    event_group_handle_ = xEventGroupCreate();
}

WebsocketProtocol::~WebsocketProtocol() {
    if (websocket_ != nullptr) {
        delete websocket_;
    }
    vEventGroupDelete(event_group_handle_);
}

void WebsocketProtocol::SendAudio(const std::vector<uint8_t>& data) {
    if (websocket_ == nullptr) {
        return;
    }

    websocket_->Send(data.data(), data.size(), true);
}

void WebsocketProtocol::SendText(const std::string& text) {
    if (websocket_ == nullptr) {
        return;
    }

    websocket_->Send(text);
}

bool WebsocketProtocol::IsAudioChannelOpened() const {
    return websocket_ != nullptr;
}

void WebsocketProtocol::CloseAudioChannel() {
    if (websocket_ != nullptr) {
        delete websocket_;
        websocket_ = nullptr;
    }
}

bool WebsocketProtocol::OpenAudioChannel() {
    if (websocket_ != nullptr) {
        delete websocket_;
    }

    std::string url = CONFIG_WEBSOCKET_URL;
    std::string token = "Bearer " + std::string(CONFIG_WEBSOCKET_ACCESS_TOKEN);
    websocket_ = Board::GetInstance().CreateWebSocket(url);
    websocket_->SetHeader("Authorization", token.c_str());

    websocket_->OnData([this](const char* data, size_t len, bool binary) {
        if (binary) {
            ESP_LOGI(TAG,"接收到数据到达binary=true");
        } else {
            // Parse JSON data
            auto root = cJSON_Parse(data);
            ESP_LOGE(TAG, "接收json数据, data: %s", data);
            cJSON_Delete(root);
        }
    });

    websocket_->OnDisconnected([this]() {
        ESP_LOGI(TAG, "Websocket disconnected");
    });

    websocket_->OnConnected([this]() {
        ESP_LOGI(TAG, "Websocket connecte success");
    });

    if (!websocket_->Connect(url.c_str())) {
        ESP_LOGE(TAG, "Failed to connect to websocket server");
        return false;
    }

    // Send hello message to describe the client
    // keys: message type, version, audio_params (format, sample_rate, channels)
    // std::string message = "{";
    // message += "\"type\":\"hello\",";
    // message += "\"version\": 1,";
    // message += "\"transport\":\"websocket\",";
    // message += "\"audio_params\":{";
    // message += "}}";
    // websocket_->Send(message);

    return true;
}
